//bitStream.cpp

#include "bitStream.h"
#include "string.h"

BitStream::~BitStream()
{
	close();
}
BitStream::BitStream()
{
	file=NULL;
}
int BitStream::open(FILE *_file, char type)
{
	if(file!=NULL)
		return 0;
	file=_file;
	prByte=0;
	restsSaver=0;
	countRBits=0;
	switch(type)
	{
		case 'r':
			fileType=0;
			break;
		case 'a':
		case 'w':
			fileType=1;
			break;			
	}	
	return 1;
}
int BitStream::close()
{
	if(file==NULL)
		return 0;
	if(countRBits!=0 && fileType==1)
	{
		if(fwrite(&restsSaver, 1, 1, file)==0)
			return 0;
	}
	file=NULL;
	return 1;
}
int BitStream::get(int count)
{
	/*if(fileType==1 || file==NULL || (count<0 || count>16))
		return -2;*/
	int temp=0;
	int res=0;
	if(countRBits>=count)
	{
		//printf("!%d[%d] ",restsSaver,countRBits);
		res=restsSaver;	
		res=res>>(countRBits-count);
		
		int temp=(8-(countRBits-count));
		restsSaver=restsSaver<<temp;
		restsSaver=restsSaver>>temp;
		countRBits=countRBits-count;		
	}
	else if((count-countRBits)<=8)
	{
		if(fread(&prByte, 1, 1, file)==0)
			return -1;
		//printf("?%d[%d] ",restsSaver,countRBits);
		res=restsSaver;
		res=res<<(count-countRBits);
		temp=prByte;
		temp=temp>>(8-(count-countRBits));
		res=res|temp;
		
		restsSaver=prByte<<(count-countRBits);
		restsSaver=restsSaver>>(count-countRBits);
		countRBits=(8-(count-countRBits));
	}
	else
	{
		//printf("$%d[%d] ",restsSaver,countRBits);
		if(fread(&prByte, 1, 1, file)==0)
			return -1;
		res=restsSaver;
		res=res<<(count-countRBits);
		temp=prByte;
		temp=temp<<(count-countRBits-8);
		res=res|temp;
		if(fread(&prByte, 1, 1, file)==0)
			return -1;
		temp=prByte;
		temp=temp>>(16-count+countRBits);
		res=res|temp;
		
		countRBits=16-count+countRBits;	
		restsSaver=prByte<<(8-countRBits);
		restsSaver=restsSaver>>(8-countRBits);
	}
	return res;	
}
int BitStream::put(unchar* values, int usedBytes)
{
	return fwrite(values, 1, usedBytes, file);
}
int BitStream::put(int value, int usedBits)
{
	/*if(fileType==0 || file==NULL || (usedBits<0 || usedBits>16))
		return 0;*/
	//printf("\nvalue -%d; count -%d",restsSaver,countRBits);
	
	int res;
	if(usedBits<(8-countRBits))
	{
		res=value;
		res=res<<((8-countRBits-usedBits)); 
		res=res|restsSaver;
		restsSaver=res;
		countRBits=countRBits+usedBits;			
	}
	else
	{
		res=restsSaver<<(usedBits-(8-countRBits));
		res=res|value;	
	
		for(int i=0; i<(countRBits+usedBits)/8; ++i)
		{
			prByte=res>>(countRBits+usedBits-(8*(i+1)));
			if(fwrite(&prByte, 1, 1, file)==0)
				return -1;	
		}
		countRBits=((countRBits+usedBits)%8);
		restsSaver=res;
		restsSaver=restsSaver<<(8-countRBits);
	}
	//printf("\tvalue -%d; count -%d 2@",restsSaver,countRBits);
	return 1;
}
